package converter;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;

public class LibreOffice2pdf {
	protected static String OS = System.getProperty("os.name");
	private static String ppt2PDF_CMD = "/opt/libreoffice4.2/program/soffice --invisible --convert-to pdf --outdir {path.pdf} {officefile}";
	static{
		if(isWin()){
			ppt2PDF_CMD="D:/libreOffice4/program/soffice --invisible --convert-to pdf --outdir {path.pdf} {officefile}";
		}
	}
	public static boolean isWin(){
		if(OS.contains("Win"))
			return true;
		return false;
	}

	public static ArrayList<String> commandLineAsList(String commandLine) {
		ArrayList<String> commands = new ArrayList<String>();
		String elt = "";
		boolean insideString = false;

		for (int i = 0; i < commandLine.length(); i++) {
			char c = commandLine.charAt(i);

			if (!insideString && (c == ' ' || c == '\t')) {
				if (elt.length() > 0) {
					commands.add(elt);
					elt = "";
				}
				continue;
			} else if (c == '"') {
				insideString = !insideString;
			}

			elt += c;
		}
		if (elt.length() > 0) {
			commands.add(elt);
		}

		return commands;
	}
	
	/**
	 * 执行方式一
	 * @param execString
	 * @return
	 * @throws Exception
	 */
	public static boolean execs(String execString) throws Exception {
		
		ArrayList<String> commands = commandLineAsList(execString);
		System.out.println(commands);
		ProcessBuilder pb = new ProcessBuilder(commands);
		pb.redirectErrorStream(true);
		Process p = pb.start();
		BufferedReader is = new BufferedReader(new InputStreamReader(
				p.getInputStream()));
		String line;
		while ((line = is.readLine()) != null) {
			String ret = line;
			System.err.println(ret);
		}
		p.waitFor();
		return true;
	}
	
	public static  void closeQuietly(Closeable closeable) {
		try {
			if (closeable != null)
				closeable.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 执行方式二
	 * @param cmd
	 * @return
	 * @throws IOException
	 */
	public static boolean execute(String cmd) throws IOException{
		Runtime runtime = Runtime.getRuntime();
		Process process = runtime.exec(cmd);
		try {
			System.out.println("----start execute----");
			System.out.println(cmd);
			StreamRedirect stdout=new StreamRedirect(process.getInputStream(),System.out); // 启动单独的线程来清空process.getInputStream()的缓冲区
			StreamRedirect stderr=new StreamRedirect(process.getErrorStream(),System.err);
			stdout.start();
			stderr.start();
			if (process.waitFor() != 0) {
				System.err.println("命令执行失败! "+process.exitValue());// p.exitValue()==0表示正常结束，1：非正常结束
				return false;
			}
			System.out.println("-------finished------");
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	/**
	 * 使用libreOffice将office文档转换为pdf
	 * 对含有图片的word文档转换效果较差
	 * @param officeFileName
	 * @return
	 * @throws Exception
	 */
	public static boolean office2pdf(String officeFileName){
		try{
			String outputFile = new File(officeFileName).getParentFile().getCanonicalPath(); 
			String cmd = ppt2PDF_CMD.replace("{path.pdf}", outputFile);
			cmd = cmd.replace("{officefile}", officeFileName);
			execs(cmd);
		 }catch(Exception e){
			 e.printStackTrace();
			 return false;
		 }
		 return true;
	}

	
	/**
	 * 使用libreOffice将office文档转换为pdf
	 * 对含有图片的word文档转换效果较差
	 * @param officeFileName
	 * @return
	 * @throws Exception
	 */
	public static boolean office2pdf_v2(String officeFileName){
		try{
			String outputFile = new File(officeFileName).getParentFile().getCanonicalPath(); 
			String cmd = ppt2PDF_CMD.replace("{path.pdf}", outputFile);
			cmd = cmd.replace("{officefile}", officeFileName);
			return execute(cmd); 
		 }catch(Exception e){
			 e.printStackTrace();
			 return false;
		 }
	}
	

	static class StreamRedirect implements Runnable {
		private InputStream is;
		private OutputStream os;
		private Thread thread;

		public StreamRedirect(InputStream is, OutputStream os) {
			this.is = is;
			this.os = os;
		}

		public void start() {
			thread = new Thread(this);
			thread.setDaemon(true);
			thread.start();
		}

		public void run() {
			try {
				BufferedReader br = new BufferedReader(
						new InputStreamReader(is));
				PrintStream printer=new PrintStream(os);
				String line;
				while ((line = br.readLine()) != null)
						printer.println(line);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		public void join() throws InterruptedException {
			thread.join();
		}
	}
	
	
	public static void main(String[] args) throws Exception{
//		office2pdf("docs/2014.doc");
//		office2pdf("docs/2015.xlsx");
//		office2pdf("docs/2016.ppt");
//		office2pdf("docs/2017.ppt");
		if(args.length > 0){
			String filename = args[0];
			office2pdf(filename);
		}
	}
}

